package edu.wy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.wy.common.result.Result;
import edu.wy.dao.UserDao;
import edu.wy.entity.Login;
import edu.wy.entity.Users;
import edu.wy.service.UserService;
import edu.wy.utils.RegexUtils;
import edu.wy.utils.UserUtils;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static edu.wy.utils.RedisContans.*;

/**
 * @author jianhong_ran
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserDao, Users> implements UserService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private UserDao userDao;

    @Resource
    private UserUtils userUtils;

    /**
     * 通过账号密码进行登录校验
     * @param login 登录信息
     * @param session session
     */
    @Override
    public Result login(Login login, HttpSession session) {
        String username = login.getUsername();
        String password = login.getPassword();

        Users user = baseMapper.selectByUsername(username);

        if (user == null || !user.getPassword().equals(password)) {
            return Result.fail("账号或密码错误");
        }

        Users user1 = BeanUtil.copyProperties(user, Users.class);

        String token = UUID.randomUUID().toString();

        //返回token
        return Result.ok(userUtils.storeUserInfoInRedis(user1,token));
    }


    /**
     * 通过手机号进行登录校验
     */
    @Override
    public Result loginByPhone(Login login, HttpSession session) {
        String phone = login.getPhone();
        //校验手机号
        if (RegexUtils.isPhoneInvalid(phone)){
            //如果不符合，返回错误信息
            return Result.fail("手机号格式错误！");
        }
        //校验验证码 从Redis中获取
        String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);
        String formCode = login.getCode();
        if (code == null || !code.equals(formCode)){
            //不一致 报错
            return Result.fail("验证码错误");
        }
        //查询用户 判断是否存在
        Users user = query().eq("phone", phone).one();
        if (user == null){
            //不存在，创建新用户
            Users user1 = new Users();
            user1.setPhone(phone);
            user1.setUsername(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
            int i = userDao.addUserByPhone(user1);
            if (i <= 0){
                //创建失败
                return Result.fail("注册失败，请稍后再试");
            }else{
                //创建成功
                user = user1;
            }
        }

        //保存用户信息到redis中
        //随机生成token
        String token = cn.hutool.core.lang.UUID.randomUUID().toString(true);

        //返回token
        return Result.ok(userUtils.storeUserInfoInRedis(user,token));
    }

    /**
     * 根据手机号进行用户注册
     */
    @Override
    public Result addUserByPhone(Login login) {
        String phone = login.getPhone();
        if (RegexUtils.isPhoneInvalid(phone)){
            //如果不符合，返回错误信息
            return Result.fail("手机号格式错误！");
        }
        String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);
        if (code == null || !code.equals(login.getCode())){
            //不一致 报错
            return Result.fail("验证码错误");
        }
        Users user = query().eq("phone", phone).one();
        if (user == null){
            Users user1 = new Users();
            user1.setPhone(phone);
            user1.setUsername(USER_NICK_NAME_PREFIX + RandomUtil.randomString(10));
            int i = userDao.addUserByPhone(user1);
            if (i > 0){
                //创建成功
                return Result.ok("注册成功，请返回登录界面进行登录！");
            }
        }
        return Result.fail("该手机号已注册");
    }

    /**
     * 退出登录 清除token记录
     */
    @Override
    public Result loginOut(String token) {
        //根据token获取到用户信息
        Users user = userUtils.getUserInfoFromRedis(token);
        stringRedisTemplate.delete(LOGIN_CODE_KEY + token);
        if (user != null){
            userDao.updateLastLoginTime(user.getUserId());
        }
        return Result.ok();
    }

    /**
     * 验证码发送
     * @param phone 电话号码
     * @param session 会话
     */
    @Override
    public Result sendCode(String phone, HttpSession session) {
        //校验手机号
        if (RegexUtils.isPhoneInvalid(phone)){
            //如果不符合，返回错误信息
            return Result.fail("手机号格式错误！");
        }

        //符合，生成验证码
        String randomNumbers = RandomUtil.randomNumbers(6);

        //保存验证码到redis
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone,randomNumbers,LOGIN_CODE_TTL, TimeUnit.MINUTES);

        //发送验证码
        log.debug("发送短信验证码成功，验证码：{}" , randomNumbers);
        //返回ok
        return Result.ok();
    }

}